package com.itheima.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.config.R;
import com.itheima.config.ThreadLocals;
import com.itheima.pojo.*;
import com.itheima.service.*;
import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.convert.IndexedData;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/order")
public class OrdersController {

    @Autowired
    private OrdersService ordersService;

    @Autowired
    private UserService userService;

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private OrderDetailService orderDetailService;

    /**
     * @param orders
     * "remark": 备注
     * "payMethod":  支付方式 1微信，2支付宝
     * "addressBookId": 地址id
     *
     * @return
     */
    @PostMapping("/submit")
    public R<String> submit(@RequestBody Orders orders){
        // 0、获取用户id
        Long UserId = (Long) ThreadLocals.getthread().get();

        // 1、查询购物车数
        LambdaQueryWrapper<ShoppingCart> shoppingCartwrapper = new LambdaQueryWrapper<>();
        shoppingCartwrapper.eq(ShoppingCart::getUserId,UserId);
        List<ShoppingCart> shoppingCarts = shoppingCartService.list(shoppingCartwrapper);


        // 2、查询用户数据
        User user = userService.getById(UserId);

        // 3、根据地址id查询地址数据  select * from addressBook where id =  addressBookId
        AddressBook addressBook = addressBookService.getById(orders.getAddressBookId());
        System.out.println(addressBook);

        // 框架自动生成的ID
        long orderId = IdWorker.getId();  //订单号

        // 购物车中所有的东西的 总金额 统计
        BigDecimal amount = new BigDecimal(0);

        // 循环 购物车
        // 4、保存订单明细数据：点了哪些菜品或套餐
        for (ShoppingCart shoppingCart : shoppingCarts) {
            // 订单明细表
            OrderDetail orderDetail = new OrderDetail();
            // 把购物车数据  拷贝到 订单明细
            BeanUtils.copyProperties(shoppingCart,orderDetail);

            // orderId单独设置
            orderDetail.setOrderId(orderId);

            // amount 金额单独设置 数量  *  单价
            BigDecimal price = shoppingCart.getAmount();

            //    这个类是为了单个物品的统计    获取购物车 里面的个个物品数量
            BigDecimal number = new BigDecimal(shoppingCart.getNumber());

            // 给订单明细表 金额赋值  单个金额 乘以 数量 的价格
            orderDetail.setAmount(price.multiply(number));

            // 把个个物品的价格的总和   放到总计里
            amount.add(orderDetail.getAmount());

            // 把封装到订单明细表的数据 添加到 订单明细 数据库表中
            orderDetailService.save(orderDetail);

        }


        // 5、保存订单数据，有许多数据需要单独设置  orders是前端传过来的订单数据 包含 备注、支付方式、和地址ID
        // 把生成的订单ID 赋值给 订单类中的ID
        orders.setId(orderId);
        // 创建订单的时间 获取系统当前时间
        orders.setOrderTime(LocalDateTime.now());
        // 订单结账时间  也是创建时间
        orders.setCheckoutTime(LocalDateTime.now());
        // 订单的状态  1待付款，2待派送，3已派送，4已完成，5已取消
        orders.setStatus(2);
        // 订单的总金额 就是上面 个数*金额的总金额封装
        orders.setAmount(amount);
        // 确定用户ID 这个订单是哪个用户下面的
        orders.setUserId(UserId);
        // 订单表的订单号赋值 因为orderId 是Long类型 所以需要转型
        orders.setNumber(String.valueOf(orderId));
        // 上面查询用户表 这里进行赋值
        orders.setUserName(user.getName());
        // 查询地址簿的收货人 赋值 给 订单的收货人
        orders.setConsignee(addressBook.getConsignee());
        // 查询地址簿的电话 赋值 给 订单的手机
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(  // 地址里面地址 进行拼接
                // 地址簿里面的省级地址是否为空 如果是空就给空字符串，
                // 不为空就把这个省级地址赋值给 订单类的地址
                (addressBook.getProvinceName() == null ? "" :
                        addressBook.getProvinceName())

                        // 地址簿里面的市级地址是否为空 如果是空就给空字符串，
                        // 不为空就把这个市级地址赋值给 订单类的地址
                        + (addressBook.getCityName() == null ? "" :
                        addressBook.getCityName())

                        // 地址簿里面的区级地址是否为空 如果是空就给空字符串，
                        // 不为空就把这个区级地址赋值给 订单类的地址
                        + (addressBook.getDistrictName() == null ? "" :
                        addressBook.getDistrictName())

                        //省+市+区域+详细地址
                        + (addressBook.getDetail() == null ? "" :
                        addressBook.getDetail())
        );

        // 把订单类封装的数据 添加到 订单表数据库
        ordersService.save(orders);

        // 6、删除当前用户的购物车数据
        LambdaQueryWrapper<ShoppingCart> qw1 = new LambdaQueryWrapper<>();
        qw1.eq(ShoppingCart::getUserId,UserId);
        shoppingCartService.remove(qw1);

        return R.success("清空购物车成功");
    }


    /**
     * 管理端订单明细 分页 订单 时间模糊查询     TODO 模糊查询 时间内的订单号  未测试
     * @param page
     * @param pageSize
     * @param number     订单号
     * @param beginTime  起始时间
     * @param endTime    终点时间
     * @return
     */
    @GetMapping("/page")
    public R<Page> orderPaget(Integer page,Integer pageSize,String number,String beginTime,String endTime){

        Page<Orders> ordersPage = new Page<>(page,pageSize);

        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(number),Orders::getNumber,number);

        if (beginTime != null && endTime != null) {

                wrapper.ge(Orders::getOrderTime, beginTime);
                wrapper.le(Orders::getCheckoutTime, endTime);
        }

        // 查询 所有用的订单， 因为管理端可以查看所有订单   StringUtils.isNotEmpty(endTime),
        ordersService.page(ordersPage,wrapper);

        return R.success(ordersPage);
    }

    /**
     * 客户端分页查询订单
     * @param page
     * @param pageSize
     * @return
     */
    @GetMapping("/userPage")
    public R<Page> userPage(Integer page,Integer pageSize){
        // 获取用户ID
        Long UserId = (Long)ThreadLocals.getthread().get();
        //分页对象
        Page<Orders> userPage = new Page<>(page, pageSize);
        // 构建条件
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Orders::getUserId,UserId);
        // 分页查询
        ordersService.page(userPage,wrapper);

        return R.success(userPage);

    }

    /**
     * 订单明细 导出
     * @param response
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response){

        // 查询全部订单明细的数据
        List<Orders> list = ordersService.list();

        ArrayList<Excel> arrayList = new ArrayList<>();
        // 循环所有订单
        for (Orders orders : list) {
            Excel excel = new Excel();
            // 每个订单数据 拷贝到 excel对象
            BeanUtils.copyProperties(orders,excel);
            arrayList.add(excel);
        }


        /**
         * EasyExcel 导入 数据来源list中
         */
        try {
            // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("订单明细", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), Excel.class).sheet("模板").doWrite(arrayList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
